package org.fastsyncer.parser.sqlserver;

import java.util.List;
import java.util.Map;

import org.fastsyncer.common.constant.ConnectorConstant;
import org.fastsyncer.common.entity.DatabaseConfig;
import org.fastsyncer.common.entity.Mapping;
import org.fastsyncer.common.entity.MappingTask;
import org.fastsyncer.connector.util.DatabaseUtil;
import org.fastsyncer.parser.framework.AbstractDatabaseParser;
import org.springframework.jdbc.core.JdbcTemplate;

// 声明一个final，使别人不能随便new对象
// 它只被调用一次，实例存在之后就不再调用了
public final class SqlServerParser extends AbstractDatabaseParser {

    // 实现单例模式的方法，通过方法来实现实例化
    // 声明一个私有的静态属性，使只被实例化一次
    private static volatile SqlServerParser instance = null;

    private SqlServerParser() {
    }

    // 声明一个公共的静态方法，外界通过调用这个方法来得到唯一的实例
    public static SqlServerParser getInstance() {
        if (null == instance) {
            synchronized (SqlServerParser.class) {
                if (null == instance) {
                    instance = new SqlServerParser();
                }
            }
        }
        return instance;
    }

    @Override
    public List<Map<String, Object>> batchQuery(MappingTask mappingTask, Integer startPos, Integer endPos) throws Exception {
        Mapping sourceMapping = mappingTask.getSourceMapping();
        // 1.获取源所有数据,例如 [{ID=123, NAME=张三11}, {ID=321, NAME=李四},...]
        // 数据源实例
        DatabaseConfig sourceConfig = (DatabaseConfig) sourceMapping.getConfig();
        JdbcTemplate sourceJdbc = super.getJdbcTemplate(sourceConfig);
        // SELECT * FROM SD_USER ORDER BY ID OFFSET(3-1) * 1000 ROWS FETCH NEXT 1000 ROWS ONLY
        // SELECT * FROM SD_USER ORDER BY ID OFFSET(?-1) * ? ROWS FETCH NEXT ? ROWS ONLY
        String sql = sourceMapping.getExecuteCommond().get(ConnectorConstant.OPERTION_QUERY);
        Object[] args = new Object[] { startPos, endPos, endPos };
        List<Map<String, Object>> rows = sourceJdbc.queryForList(sql, args);

        // 释放连接
        DatabaseUtil.close(sourceJdbc);
        return rows;
    }

}
